package com.youhong.teethcare.ryan;

import android.app.NotificationManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;

import com.youhong.teethcare.R;
import com.youhong.teethcare.dfu.DfuService;
import com.youhong.teethcare.settingpage.DfuActivity;
import com.youhong.teethcare.utils.Tools;

import java.io.File;

import no.nordicsemi.android.dfu.DfuProgressListener;
import no.nordicsemi.android.dfu.DfuProgressListenerAdapter;
import no.nordicsemi.android.dfu.DfuServiceInitiator;
import no.nordicsemi.android.dfu.DfuServiceListenerHelper;

/**
 * Created by Administrator on 2018/4/25 0025.
 */

public class DfuTool {

    private static final String PREFS_DEVICE_NAME = "no.nordicsemi.android.nrftoolbox.dfu.PREFS_DEVICE_NAME";
    private static final String PREFS_FILE_NAME = "no.nordicsemi.android.nrftoolbox.dfu.PREFS_FILE_NAME";
    private static final String PREFS_FILE_TYPE = "no.nordicsemi.android.nrftoolbox.dfu.PREFS_FILE_TYPE";
    private static final String PREFS_FILE_SCOPE = "no.nordicsemi.android.nrftoolbox.dfu.PREFS_FILE_SCOPE";
    private static final String PREFS_FILE_SIZE = "no.nordicsemi.android.nrftoolbox.dfu.PREFS_FILE_SIZE";

    public static final int PROGRESS_DFU_PREPARE = -2;
    //public static final int PROGRESS_DFU_START = -1;
    public static final int PROGRESS_DFU_FAILD = -3;
    public static final int PROGRESS_READY = 0;
    public static final int PROGRESS_FINISHED = 101;
    public static final int PROGRESS_FAILED = 103;
    private static final String DFU_BC_NAME = "dfutarg";


    BluetoothAdapter mBluetoothAdapter = null;
    Context mContext;
    String mFirmwarePath;
    DfuTool.DfuStateListener mDfuStateListener;

    //需要在Dfu功能的Activity 里创建一个该类的对象进行操作。

    public DfuTool(Context context, String firmwarePath, DfuTool.DfuStateListener mDfuStateListener) {

        this.mContext = context;
        this.mFirmwarePath = firmwarePath;
        this.mDfuStateListener = mDfuStateListener;

        final BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
    }

    boolean isScanning = false;

    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {

            final String dev_name = Tools.decodeDeviceName(scanRecord);
            if (dev_name != null && dev_name.toLowerCase().contains("dfutarg")) {

                //避免多线程异步时出现的执行乱序.
                if (!isScanning)
                    return;
                startScan(false);
                startDfu(device);
            }

        }
    };

    Handler mHandler = new Handler();

    public void startScan(boolean enable) {
        // TODO Auto-generated method stub

        if (enable) {
            mHandler.postDelayed(new Runnable() {

                @Override
                public void run() {
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    isScanning = false;
                   /* bt_cancle.setText(getResources().getString(
                            R.string.start_scan));*/
                }
            }, 20000);
            mBluetoothAdapter.startLeScan(mLeScanCallback);
            isScanning = true;

        } else {
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
            isScanning = false;
        }
    }

    private void startDfu(BluetoothDevice device) {

        DfuServiceListenerHelper.registerProgressListener(mContext, mDfuProgressListener);

      /*  if (isDfuServiceRunning()) {
            showUploadCancelDialog();
            return;
        }*/

// Check whether the selected file is a HEX file (we are just checking the extension)
      /*  if (!mStatusOk) {
            Toast.makeText(this, R.string.dfu_file_status_invalid_message, Toast.LENGTH_LONG).show();
            return;
        }*/
// Save current state in order to restore it if user quit the Activity
        final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
        final SharedPreferences.Editor editor = preferences.edit();
        File file = new File(mFirmwarePath);

         /*   editor.putString(PREFS_DEVICE_NAME, mSelectedDevice.getName());
            editor.putString(PREFS_FILE_NAME, mFileNameView.getText().toString());
            editor.putString(PREFS_FILE_TYPE, mFileTypeView.getText().toString());*/
        editor.putString(PREFS_FILE_SCOPE, "All");
        editor.putString(PREFS_FILE_SIZE, file.length() + "");
        editor.apply();

//showProgressBar();

        final boolean keepBond = false;
        final boolean forceDfu = false;
        final boolean enablePRNs = false;
        String value = String.valueOf(DfuServiceInitiator.DEFAULT_PRN_VALUE);

        int numberOfPackets;
        try {
            numberOfPackets = Integer.parseInt(value);
        } catch (final NumberFormatException e) {
            numberOfPackets = DfuServiceInitiator.DEFAULT_PRN_VALUE;
        }

        final DfuServiceInitiator starter = new DfuServiceInitiator(device.getAddress())
                .setDeviceName(device.getName())
                .setKeepBond(keepBond)
                .setForceDfu(forceDfu)
                .setPacketsReceiptNotificationsEnabled(enablePRNs)
                .setPacketsReceiptNotificationsValue(numberOfPackets)
                .setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true);
        if(Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
            starter.createDfuNotificationChannel(mContext);
        }

     /*   if (mFileType == DfuService.TYPE_AUTO) {*/
        starter.setZip(Uri.fromFile(new File(mFirmwarePath)), null);
       /* if (mScope != null)
            starter.setScope();*/
       /* } else {
            starter.setBinOrHex(mFileType, mFileStreamUri, mFilePath).setInitFile(mInitFileStreamUri, mInitFilePath);
        }*/
        starter.start(mContext, DfuService.class);
    }

    private final DfuProgressListener mDfuProgressListener = new DfuProgressListenerAdapter() {
        @Override
        public void onDeviceConnecting(final String deviceAddress) {

        }

        @Override
        public void onDfuProcessStarting(final String deviceAddress) {

            if (mDfuStateListener != null) {

                mDfuStateListener.onStateChange(PROGRESS_READY);

            }

        }

        @Override
        public void onEnablingDfuMode(final String deviceAddress) {

        }

        @Override
        public void onFirmwareValidating(final String deviceAddress) {

        }

        @Override
        public void onDeviceDisconnecting(final String deviceAddress) {

        }

        @Override
        public void onDfuCompleted(final String deviceAddress) {

            if (mDfuStateListener != null) {

                mDfuStateListener.onStateChange(PROGRESS_FINISHED);

            }
        }

        @Override
        public void onDfuAborted(final String deviceAddress) {
            // let's wait a bit until we cancel the notification. When canceled immediately it will be recreated by service again.
            if (mDfuStateListener != null) {

                mDfuStateListener.onStateChange(PROGRESS_FAILED);
            }

            new Handler().postDelayed(() -> {
                //onUploadCanceled();

                // if this activity is still open and upload process was completed, cancel the notification
                final NotificationManager manager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
                manager.cancel(DfuService.NOTIFICATION_ID);
            }, 200);
        }

        @Override
        public void onProgressChanged(final String deviceAddress, final int percent, final float speed, final float avgSpeed, final int currentPart, final int partsTotal) {

            //Log.e("abc", percent + "");
            if (mDfuStateListener != null) {

                mDfuStateListener.onStateChange(percent);


            }
            /*       if (partsTotal > 1)
                mTextUploading.setText(getString(R.string.dfu_status_uploading_part, currentPart, partsTotal));
            else
                mTextUploading.setText(R.string.dfu_status_uploading);*/
        }

        @Override
        public void onError(final String deviceAddress, final int error, final int errorType, final String message) {
            if (mDfuStateListener != null) {

                mDfuStateListener.onStateChange(PROGRESS_FAILED);

            }
            // We have to wait a bit before canceling notification. This is called before DfuService creates the last notification.
            new Handler().postDelayed(() -> {
                // if this activity is still open and upload process was completed, cancel the notification
                final NotificationManager manager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
                manager.cancel(DfuService.NOTIFICATION_ID);
            }, 200);
       /* } else
        {
            //  mDfuError = message;
        }*/
        }
    };

    public interface DfuStateListener {

        public void onStateChange(int stateCode);

    }
}
